package com.cloud.drore.eboos.common.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.cloud.drore.eboos.common.base.ResultMessage;
import com.cloud.drore.eboos.common.entity.base.UserInfo;
import com.cloud.drore.eboos.common.util.JedisUtils;
import com.cloud.drore.eboos.common.util.LocalData;
import com.cloud.drore.eboos.common.util.security.Codec;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

/**
 * 浙江卓锐科技股份有限公司 版权所有 © Copyright 2018<br>
 *
 * @Description: <br>
 * @Project: eboos <br>
 * @CreateDate: Created in 2018/4/18 11:54 <br>
 * @Author: <a href="836327318@qq.com">吴昌益</a>
 */
@Aspect
@Component
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class AvoidDuplicateAspect {

    @Autowired
    private JedisUtils jedisUtils;

    private static String PARAM_POINT = ".";
    private static String PARAM_LINE = "_";
    private static String PARAM_TOKEN_FLAG =  "tokenFlag";

    /**
     * @ClassName: AvoidDuplicateAspect
     * @Return:
     * @Decription: method proxy of avoid duplicate aspect
     * @CreateDate: Created in 2018/4/18 11:36
     * @Author: <a href="836327318@qq.com">吴昌益</a>
     * @Modify:
     */
    @Around(value =  "@annotation(com.cloud.drore.eboos.common.annotation.AvoidDuplicate)")
    public Object excute(ProceedingJoinPoint joinPoint) throws Throwable{
        try {
            Object result = null;
            Object[] args = joinPoint.getArgs();
            //redis加锁
            result =  validation(joinPoint);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultMessage.error(8300,"请不要重复提交！！");
        }
    }

    public Object validation(ProceedingJoinPoint  joinPoint) throws Throwable {
        String cachekey =  getCacheKey(joinPoint.toLongString(),joinPoint.getArgs());
        //redis加锁
        boolean lock =  jedisUtils.tryGetDistributedLock(PARAM_TOKEN_FLAG+cachekey, cachekey, 60000);
        if(lock){
            //加锁成功
            //执行方法
            Object funcResult = joinPoint.proceed();
            //方法执行完之后进行解锁
            jedisUtils.releaseDistributedLock(PARAM_TOKEN_FLAG +  cachekey, cachekey);
            return funcResult;
        }else{
            //锁已存在
            return ResultMessage.error(8300,"请不要重复提交！！");
        }
    }

    private String getCacheKey(String targetName, Object[] arguments) {
        StringBuffer sb = new StringBuffer();

        UserInfo userInfo = LocalData.getCurrentUser();
        if(userInfo!=null)
            sb.append(userInfo.getId()+PARAM_LINE+LocalData.getCurrentUser().getUsername()).append(PARAM_POINT);

        sb.append(targetName);
        if ((arguments != null) && (arguments.length != 0)) {
            for (int i = 0; i < arguments.length; i++) {
                // 处理空指针 基本数据类型
                sb.append(PARAM_POINT).append(arguments[i] == null ? "" : getValue(arguments[i]));
            }
        }
        return Codec.encodeMd5(sb.toString());
    }

    public String getValue(Object obj) {
        if (obj.getClass().isArray()) {
            StringBuffer buf = new StringBuffer();
            Object[] array = (Object[]) obj;
            for (Object value : array) {
                if (value != null) {
                    buf.append(value.toString()).append(",");
                }
            }
            return buf.toString();
        }
        return JSONObject.toJSONString(obj);
    }
}

